package top.csy8888.rabbitmq.demo;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.DeliverCallback;

import java.nio.charset.StandardCharsets;

/**
 * @author CSY
 * @date 2025 - 10 - 09
 * 消费者
 */
public class Consumer {
    /**
     * 队列名称
     */
    private static final String QUEUE_NAME = "test";
    /**
     * 连接工厂
     */
    private static final ConnectionFactory connectionFactory;

    /**
     * 初始化连接工厂
     */
    static {
        connectionFactory = new ConnectionFactory();
        //设置本机地址
        connectionFactory.setHost("127.0.0.1");
        //5672是客户端访问端口，15672是控制台网页访问端口
        //设置访问端口
        connectionFactory.setPort(5672);
    }

    /**
     * 接收消息
     */
    public static void receive() {
        try{
            // 创建连接
            Connection connection = connectionFactory.newConnection();
            // 使用连接对象构建一个消息通信的通道（Channel）
            Channel channel = connection.createChannel();
            // 创建队列 （如果创建的队列存在则不会创建）
            // 参数一：队列的名称
            // 参数二：队列是否持久化 - true表示持久化
            // 参数三：是否排他（true表示排他），
            //       排他性指的是队列只对首次创建的Connection可见，
            //       false表示可以被所有Connection可见
            // 参数四：设置为true表示断开连接时，自动删除队列
            // 参数五：队列的其他属性设置，是一个map集合
            channel.queueDeclare(QUEUE_NAME,false,false,false,null);

            // 创建一个接收消息所需要的回调处理器
            // consumerTag：消费者的唯一标识（消费者的ID）
            // delivery：消息的载体
            DeliverCallback deliverCallback = (consumerTag, delivery) -> {
                // 获取消息(消息队列中的内容是字节数组，因此需要转换为String)
                String message = new String(delivery.getBody(), StandardCharsets.UTF_8);
                System.out.println("consumerTag："+consumerTag);
                System.out.println("message："+message);
            };
            // 订阅消息
            // 参数一：队列名称
            // 参数二：是否是自动签收（true表示自动签收），签收后消息将会从队列中删除
            //       自动签收就是消息处理完后会自动给rabbitmq回馈一个消息表示处理完毕
            // 参数三：消息的回调处理器（处理消息的核心逻辑）
            // 参数四：消费者取消订阅时的回调处理器，会传入一个consumerTag签收标签
            channel.basicConsume(QUEUE_NAME, true, deliverCallback, consumerTag -> {});
        }catch (Exception e){
            throw new RuntimeException("消费异常",e);
        }
    }

    public static void main(String[] args) {
        receive();
    }
}
